use crate::config::{LspManagerConfig, LspServerConfig};
use std::collections::HashMap;
use std::process::{Child, Command, Stdio};
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::sync::{Mutex, RwLock};
use tokio::time::interval;
use tracing::{debug, error, info, warn};
use uuid::Uuid;

/// LSP服务器状态
#[derive(Debug, Clone, PartialEq)]
pub enum LspServerStatus {
    /// 未启动
    NotStarted,
    /// 启动中
    Starting,
    /// 运行中
    Running,
    /// 停止中
    Stopping,
    /// 已停止
    Stopped,
    /// 错误状态
    Error(String),
    /// 崩溃
    Crashed,
}

/// LSP服务器实例信息
#[derive(Debug)]
pub struct LspServerInstance {
    /// 服务器ID
    pub id: String,
    /// 语言标识
    pub language: String,
    /// 服务器配置
    pub config: LspServerConfig,
    /// 当前状态
    pub status: LspServerStatus,
    /// 进程句柄
    pub process: Option<Child>,
    /// 启动时间
    pub started_at: Option<Instant>,
    /// 最后活动时间
    pub last_activity: Instant,
    /// 重启次数
    pub restart_count: u32,
    /// 最后健康检查时间
    pub last_health_check: Instant,
    /// 资源使用统计
    pub resource_stats: ResourceStats,
}

/// 资源使用统计
#[derive(Debug, Default, Clone)]
pub struct ResourceStats {
    /// CPU使用率 (百分比)
    pub cpu_usage: f64,
    /// 内存使用量 (字节)
    pub memory_usage: u64,
    /// 处理的请求数量
    pub requests_handled: u64,
    /// 平均响应时间 (毫秒)
    pub avg_response_time: f64,
    /// 错误计数
    pub error_count: u64,
}

/// LSP服务器管理器
pub struct LspServerManager {
    /// 配置
    config: Arc<RwLock<LspManagerConfig>>,
    /// 服务器实例
    servers: Arc<Mutex<HashMap<String, LspServerInstance>>>,
    /// 是否正在运行
    running: Arc<Mutex<bool>>,
}

impl LspServerManager {
    /// 创建新的LSP服务器管理器
    pub fn new(config: LspManagerConfig) -> Self {
        Self {
            config: Arc::new(RwLock::new(config)),
            servers: Arc::new(Mutex::new(HashMap::new())),
            running: Arc::new(Mutex::new(false)),
        }
    }

    /// 启动管理器
    pub async fn start(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let mut running = self.running.lock().await;
        if *running {
            return Ok(());
        }
        *running = true;
        drop(running);

        info!("Starting LSP Server Manager");

        // 启动健康检查任务
        self.start_health_check_task().await;

        // 启动资源监控任务
        self.start_resource_monitoring_task().await;

        Ok(())
    }

    /// 停止管理器
    pub async fn stop(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let mut running = self.running.lock().await;
        if !*running {
            return Ok(());
        }
        *running = false;
        drop(running);

        info!("Stopping LSP Server Manager");

        // 停止所有服务器
        let mut servers = self.servers.lock().await;
        for (language, server) in servers.iter_mut() {
            if let Err(e) = self.stop_server_internal(server).await {
                error!("Failed to stop server for {}: {}", language, e);
            }
        }
        servers.clear();

        Ok(())
    }

    /// 启动指定语言的LSP服务器
    pub async fn start_server(&self, language: &str) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
        let config = self.config.read().await;
        let server_config = config.servers.get(language)
            .ok_or_else(|| format!("No server configuration found for language: {}", language))?;

        if !server_config.enabled {
            return Err(format!("Server for language {} is disabled", language).into());
        }

        let mut servers = self.servers.lock().await;
        
        // 检查是否已经有运行中的服务器
        if let Some(existing) = servers.get(language) {
            match existing.status {
                LspServerStatus::Running => {
                    return Ok(existing.id.clone());
                }
                LspServerStatus::Starting => {
                    return Ok(existing.id.clone());
                }
                _ => {
                    // 移除旧的实例
                    servers.remove(language);
                }
            }
        }

        let server_id = Uuid::new_v4().to_string();
        info!("Starting LSP server for {}: {}", language, server_id);

        // 创建服务器实例
        let mut server_instance = LspServerInstance {
            id: server_id.clone(),
            language: language.to_string(),
            config: server_config.clone(),
            status: LspServerStatus::Starting,
            process: None,
            started_at: None,
            last_activity: Instant::now(),
            restart_count: 0,
            last_health_check: Instant::now(),
            resource_stats: ResourceStats::default(),
        };

        // 启动进程
        match self.start_server_process(&mut server_instance).await {
            Ok(()) => {
                server_instance.status = LspServerStatus::Running;
                server_instance.started_at = Some(Instant::now());
                servers.insert(language.to_string(), server_instance);
                info!("LSP server started successfully for {}: {}", language, server_id);
                Ok(server_id)
            }
            Err(e) => {
                server_instance.status = LspServerStatus::Error(e.to_string());
                servers.insert(language.to_string(), server_instance);
                error!("Failed to start LSP server for {}: {}", language, e);
                Err(e)
            }
        }
    }

    /// 停止指定语言的LSP服务器
    pub async fn stop_server(&self, language: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        let mut servers = self.servers.lock().await;
        if let Some(server) = servers.get_mut(language) {
            self.stop_server_internal(server).await?;
            servers.remove(language);
            info!("LSP server stopped for {}", language);
        }
        Ok(())
    }

    /// 重启指定语言的LSP服务器
    pub async fn restart_server(&self, language: &str) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
        info!("Restarting LSP server for {}", language);
        
        // 先停止服务器
        if let Err(e) = self.stop_server(language).await {
            warn!("Failed to stop server for {} during restart: {}", language, e);
        }

        // 等待一小段时间
        tokio::time::sleep(Duration::from_millis(500)).await;

        // 重新启动服务器
        self.start_server(language).await
    }

    /// 获取服务器状态
    pub async fn get_server_status(&self, language: &str) -> Option<LspServerStatus> {
        let servers = self.servers.lock().await;
        servers.get(language).map(|server| server.status.clone())
    }

    /// 获取所有服务器状态
    pub async fn get_all_server_status(&self) -> HashMap<String, LspServerStatus> {
        let servers = self.servers.lock().await;
        servers.iter()
            .map(|(lang, server)| (lang.clone(), server.status.clone()))
            .collect()
    }

    /// 获取服务器资源统计
    pub async fn get_server_stats(&self, language: &str) -> Option<ResourceStats> {
        let servers = self.servers.lock().await;
        servers.get(language).map(|server| server.resource_stats.clone())
    }

    /// 内部启动服务器进程
    async fn start_server_process(&self, server: &mut LspServerInstance) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        debug!("Starting process for {}: {} {:?}", server.language, server.config.command, server.config.args);

        let mut command = Command::new(&server.config.command);
        command.args(&server.config.args);
        command.stdin(Stdio::piped());
        command.stdout(Stdio::piped());
        command.stderr(Stdio::piped());

        // 设置工作目录
        if let Some(working_dir) = &server.config.working_directory {
            command.current_dir(working_dir);
        }

        // 设置环境变量
        for (key, value) in &server.config.env {
            command.env(key, value);
        }

        let child = command.spawn()
            .map_err(|e| format!("Failed to spawn process for {}: {}", server.language, e))?;

        server.process = Some(child);
        Ok(())
    }

    /// 内部停止服务器
    async fn stop_server_internal(&self, server: &mut LspServerInstance) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        server.status = LspServerStatus::Stopping;

        if let Some(mut process) = server.process.take() {
            // 尝试优雅关闭
            if let Err(e) = process.kill() {
                warn!("Failed to kill process for {}: {}", server.language, e);
            }

            // 等待进程结束
            if let Err(e) = process.wait() {
                warn!("Failed to wait for process for {}: {}", server.language, e);
            }
        }

        server.status = LspServerStatus::Stopped;
        Ok(())
    }

    /// 启动健康检查任务
    async fn start_health_check_task(&self) {
        let servers = Arc::clone(&self.servers);
        let running = Arc::clone(&self.running);
        let config = Arc::clone(&self.config);

        tokio::spawn(async move {
            let mut interval = interval(Duration::from_secs(30)); // 每30秒检查一次

            loop {
                interval.tick().await;

                let is_running = {
                    let running_guard = running.lock().await;
                    *running_guard
                };

                if !is_running {
                    break;
                }

                let mut servers_guard = servers.lock().await;
                let config_guard = config.read().await;

                for (language, server) in servers_guard.iter_mut() {
                    // 检查服务器健康状态
                    if let Err(e) = Self::check_server_health(server, &config_guard).await {
                        error!("Health check failed for {}: {}", language, e);

                        // 如果启用了自动重启且重启次数未超限
                        if server.config.auto_restart && server.restart_count < server.config.max_restart_count {
                            warn!("Attempting to restart server for {}", language);
                            server.restart_count += 1;
                            server.status = LspServerStatus::Crashed;

                            // 这里应该触发重启逻辑
                            // 由于我们在锁内，不能直接调用restart_server，需要标记后在外部处理
                        }
                    }
                }
            }
        });
    }

    /// 启动资源监控任务
    async fn start_resource_monitoring_task(&self) {
        let servers = Arc::clone(&self.servers);
        let running = Arc::clone(&self.running);

        tokio::spawn(async move {
            let mut interval = interval(Duration::from_secs(10)); // 每10秒监控一次

            loop {
                interval.tick().await;

                let is_running = {
                    let running_guard = running.lock().await;
                    *running_guard
                };

                if !is_running {
                    break;
                }

                let mut servers_guard = servers.lock().await;

                for (language, server) in servers_guard.iter_mut() {
                    if server.status == LspServerStatus::Running {
                        if let Err(e) = Self::update_resource_stats(server).await {
                            debug!("Failed to update resource stats for {}: {}", language, e);
                        }
                    }
                }
            }
        });
    }

    /// 检查服务器健康状态
    async fn check_server_health(
        server: &mut LspServerInstance,
        _config: &LspManagerConfig,
    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        server.last_health_check = Instant::now();

        // 检查进程是否还在运行
        if let Some(process) = &mut server.process {
            match process.try_wait() {
                Ok(Some(exit_status)) => {
                    // 进程已退出
                    return Err(format!("Process exited with status: {:?}", exit_status).into());
                }
                Ok(None) => {
                    // 进程仍在运行
                    debug!("Server {} is healthy", server.language);
                }
                Err(e) => {
                    return Err(format!("Failed to check process status: {}", e).into());
                }
            }
        } else {
            return Err("No process found".into());
        }

        Ok(())
    }

    /// 更新资源使用统计
    async fn update_resource_stats(
        server: &mut LspServerInstance,
    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        if let Some(process) = &server.process {
            let pid = process.id();

            // 这里应该使用系统API获取进程的资源使用情况
            // 由于复杂性，这里只是模拟数据
            server.resource_stats.cpu_usage = 0.0; // 实际应该获取真实的CPU使用率
            server.resource_stats.memory_usage = 0; // 实际应该获取真实的内存使用量

            debug!("Updated resource stats for {} (PID: {})", server.language, pid);
        }

        Ok(())
    }

    /// 根据文件扩展名发现合适的LSP服务器
    pub async fn discover_server_for_file(&self, file_path: &str) -> Option<String> {
        let extension = std::path::Path::new(file_path)
            .extension()
            .and_then(|ext| ext.to_str())
            .map(|ext| format!(".{}", ext))?;

        let config = self.config.read().await;
        for (language, server_config) in &config.servers {
            if server_config.enabled && server_config.file_extensions.contains(&extension) {
                return Some(language.clone());
            }
        }

        None
    }

    /// 更新服务器配置
    pub async fn update_config(&self, new_config: LspManagerConfig) {
        let mut config = self.config.write().await;
        *config = new_config;
        info!("LSP manager configuration updated");
    }

    /// 获取当前配置
    pub async fn get_config(&self) -> LspManagerConfig {
        let config = self.config.read().await;
        config.clone()
    }
}
